//
// Created by LiuYou on 2021/5/23.
//

#include <cstdlib>
#include <unistd.h>
#include <csignal>

static void interruptHandler(int i);

/**
 * @brief 注意这个程序还没有实现完全。
 */
int main() {
    signal(SIGINT, interruptHandler);

    sigset_t set{};
    sigset_t oset{};
    // TODO 注意: 这个对象是为了保存之前的状态。
    sigset_t saveset{};
    sigemptyset(&set);
    sigaddset(&set, SIGINT);


    // TODO 改进
    sigprocmask(SIG_UNBLOCK, &set, &saveset);

    for (int i = 0; i < 1000; ++i) {
        // TODO 注意:
        //  不能决定信号什么时候来, 但是能决定信号什么时候响应。
        //  但是这个是有错误的。因为我们要保证执行了我这个模块, 不影响外部的环境(整体的状态)。
        sigprocmask(SIG_BLOCK, &set, nullptr);



        // 这里使用这面这条语句也是可以的。
//        sigprocmask(SIG_BLOCK, &set, &oset);

        // TODO 注意: 我希望在 forj 这个循环执行期间不受信号影响。
        for (int j = 0; j < 5; ++j) {
            write(1, "*", 1);
            sleep(1);
        }
        write(1, "\n", 1);

        sigprocmask(SIG_UNBLOCK, &set, nullptr);

        // 与上面的语句搭配使用
//        sigprocmask(SIG_SETMASK, &oset, nullptr);

    }

    // TODO 注意: 改进
    //  fori 之前和之后的 sigprocmask()函数 确保了进入这个模块和离开这个模块
    //  整体状态是不受影响的。
    sigprocmask(SIG_SETMASK, &saveset, nullptr);


    std::exit(0);
}

static void interruptHandler(int i) {
    write(1, "!", 1);
}
